/*
 * Copyright 2022-2025 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.instancio.test.features.generator.seed;

import org.instancio.Instancio;
import org.instancio.Result;
import org.instancio.junit.InstancioExtension;
import org.instancio.junit.Seed;
import org.instancio.test.support.tags.Feature;
import org.instancio.test.support.tags.FeatureTag;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import static org.assertj.core.api.Assertions.assertThat;

@FeatureTag(Feature.SEED)
@ExtendWith(InstancioExtension.class)
class WithSeedAnnotationTest {

    private static final long SEED = 1234;
    private static final String EXPECTED_RANDOM_STRING = "XTYQHJHH";

    @Test
    @Seed(SEED)
    @DisplayName("Verify string created from @Seed(...) value")
    void assertStringCreatedFromSuppliedSeed() {
        final Result<String> result = Instancio.of(String.class).asResult();

        assertThat(result.getSeed()).isEqualTo(SEED);
        assertThat(result.get()).isEqualTo(EXPECTED_RANDOM_STRING);
    }

    @Test
    @Seed(SEED)
    @DisplayName("Separate calls to create() within the same test method should produce distinct values")
    void eachCreateInstanceGeneratesDistinctValue() {
        final String result1 = Instancio.create(String.class);
        final String result2 = Instancio.create(String.class);
        assertThat(result1).isNotEqualTo(result2);
    }

    @Test
    @Seed(SEED)
    @DisplayName("withSeed() should take precedence over the @Seed annotation")
    void modelSeedShouldTakePrecedenceOverSeedAnnotation() {
        final Result<String> result1 = Instancio.of(String.class).asResult();

        final long otherSeed = 4567;
        final Result<String> result2 = Instancio.of(String.class)
                .withSeed(otherSeed)
                .asResult();

        assertThat(result1.getSeed()).isEqualTo(SEED);
        assertThat(result2.getSeed()).isEqualTo(otherSeed);

        assertThat(result1.get())
                .isEqualTo(EXPECTED_RANDOM_STRING)
                .isNotEqualTo(result2.get());
    }
}
